import SwiftUI

struct CircularArcView: View {
    let startAngle: Double = 130
    let endAngle: Double = 410
    let maxValue: CGFloat = 160
    let increment: CGFloat = 20
    let totalSteps: Int = 9
    let radius: CGFloat = 100
    let labelOffset: CGFloat = 0
    
    @Binding var progress: Double

    var body: some View {
        ZStack {
            // 圆弧
            Arc(startAngle: startAngle, endAngle: endAngle, radian: 1.835, progress: 100)
                .stroke(Color("spbg"), lineWidth: 2)
                .frame(width: 200, height: 200)
            
            Arc(startAngle: startAngle, endAngle: endAngle, radian: 2.35, progress: 100)
                .stroke(Color("spbg"), lineWidth: 2)
                .frame(width: 200, height: 200)
            
            Arc(startAngle: startAngle, endAngle: endAngle, radian: 2.3, progress: progress / 1.6)
                .stroke(Color("coco"), lineWidth: 4)
                .frame(width: 200, height: 200)
                .animation(.interpolatingSpring(stiffness: 1000, damping: 100), value: progress ) // 使用更柔和的弹性动画

            Arc(startAngle: startAngle, endAngle: endAngle, radian: 2.05, progress: progress / 1.6)
                .stroke(Color("spbg"), lineWidth: 22)
                .frame(width: 200, height: 200)
                .animation(.interpolatingSpring(stiffness: 1000, damping: 100), value: progress) // 同样应用平滑的弹性动画


            ForEach(0..<totalSteps, id: \.self) { index in
                addTick(at: index)
            }
        }
        .frame(width: 200, height: 200)
       
    }

    func addTick(at index: Int) -> some View {
        let angle = Angle(degrees: startAngle + Double(index) * (endAngle - startAngle) / Double(totalSteps - 1))
        
        let tickStart = CGPoint(
            x: 100 + (radius + 10) * cos(angle.radians),
            y: 100 + (radius + 10) * sin(angle.radians)
        )

        let tickEnd = CGPoint(
            x: 100 + (radius + 20) * cos(angle.radians),
            y: 100 + (radius + 20) * sin(angle.radians)
        )

        return Group {
            // 添加主刻度线
            Path { path in
                path.move(to: tickStart)
                path.addLine(to: tickEnd)
            }
            .stroke(Color("coco"), lineWidth: 2)

            // 添加数字
            if index < totalSteps {
                let labelPosition = CGPoint(
                    x: 100 + (radius + labelOffset) * cos(angle.radians),
                    y: 100 + (radius + labelOffset) * sin(angle.radians)
                )
                Text("\(Int(increment * CGFloat(index)))")
                    .position(x: labelPosition.x, y: labelPosition.y)
                    .font(.caption)
            }

            // 添加中间刻度，仅在不是最后一个主刻度的情况下
            if index < totalSteps - 1 {
                ForEach(1..<6, id: \.self) { i in
                    let intermediateAngle = angle.degrees + Double(i) * ((endAngle - startAngle) / Double(totalSteps - 1) / 6)
                    let tickIntermediateStart = CGPoint(
                        x: 100 + (radius + 10) * cos(Angle(degrees: intermediateAngle).radians),
                        y: 100 + (radius + 10) * sin(Angle(degrees: intermediateAngle).radians)
                    )

                    let tickIntermediateEnd = CGPoint(
                        x: 100 + (radius + 15) * cos(Angle(degrees: intermediateAngle).radians),
                        y: 100 + (radius + 15) * sin(Angle(degrees: intermediateAngle).radians)
                    )

                    // 添加小刻度线
                    Path { path in
                        path.move(to: tickIntermediateStart)
                        path.addLine(to: tickIntermediateEnd)
                    }
                    .stroke(Color("coco"), lineWidth: 1)
                }
            }
        }
    }
}

struct Arc: Shape {
    var startAngle: Double
    var endAngle: Double
    var radian: Double
    var progress: Double

    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = min(rect.width, rect.height) / radian

        var path = Path()
        let startRadians = startAngle * .pi / 180

        path.move(to: CGPoint(x: center.x + radius * CGFloat(cos(startRadians)),
                              y: center.y + radius * CGFloat(sin(startRadians))))
        path.addArc(center: center, radius: radius,
                     startAngle: Angle(degrees: startAngle),
                     endAngle: Angle(degrees: startAngle + (progress * (endAngle - startAngle) / 100)),
                     clockwise: false)

        return path
    }
}

// 预览
struct CircularArcView_Previews: PreviewProvider {
    @State static var progress: Double = 0

    static var previews: some View {
        CircularArcView(progress: $progress)
    }
}
